package main

import (
	"errors"
	"fmt"
)

//1. 实现一个函数，接受若干个float64（用不定长参数），返回这些参数乘积的倒数，除数为0时返回error
func reciprocal(args ...float64) (res float64, err error) {
	var product float64 = 1
	for _, f := range args {
		product *= f
	}
	if product == 0 {
		err = errors.New("integer divde by zero")
		return
	}
	fmt.Println(product)
	res = 1 / product
	return
}

//2. 上题用递归实现
func recursion(args ...float64) (res float64, err error) {
	if len(args) > 1 {
		args[1] *= args[0]
		args = append(args[0:0], args[1:]...)
		recursion(args...)
	}
	if args[0] == 0 {
		return -1, errors.New("integer divde by zero")
	}
	return 1 / args[0], nil
}

//3. 定义两个接口：鱼类和爬行动物，再定义一个结构体：青蛙，同时实现上述两个接口
type aquatic interface {
	swim()
}

type reptile interface {
	crawl()
}

type frog struct {
	name string
}

func (f frog) swim() {
	fmt.Println("游泳！")
}

func (f frog) crawl() {
	fmt.Println("跳!")
}

//4. 实现函数func square(num interface{}) interface{}，计算一个interface{}的平方，interface{}允许是4种类型：float32、float64、int、byte
func square(num interface{}) interface{} {
	switch v := num.(type) {
	case float32:
		return v * v
	case float64:
		return v * v
	case int:
		return v * v
	case byte:
		return v * v
	default:
		return "num 类型不正确！ "
	}
}

func main() {
	//1. 实现一个函数，接受若干个float64（用不定长参数），返回这些参数乘积的倒数，除数为0时返回error
	if product, err := reciprocal(2.55, 3.6, -1.5); err == nil {
		fmt.Println(product)
	} else {
		fmt.Println(err)
	}
	fmt.Printf("%f\n", -13.77*-0.07262164124909223)
	fmt.Println("-----------------")

	//2. 上题用递归实现
	if product, err := recursion(2.55, 3.6, -1.5); err == nil {
		fmt.Println(product)
	} else {
		fmt.Println(err)
	}
	fmt.Println("-----------------")

	//3. 定义两个接口：鱼类和爬行动物，再定义一个结构体：青蛙，同时实现上述两个接口
	var a aquatic
	var r reptile
	f := frog{"张三"}
	a = f
	a.swim()
	r = f
	r.crawl()
	fmt.Println("-----------------")

	//4. 实现函数func square(num interface{}) interface{}，计算一个interface{}的平方，interface{}允许是4种类型：float32、float64、int、byte
	if v, ok := square(float64(1.5)).(float64); ok {
		fmt.Printf("%T, %f\n", v, v)
	}
	fmt.Printf("%T, %f\n", square(float32(1.5)), square(float32(2.5)))
	fmt.Printf("%T, %d\n", square(5), square(5))
	fmt.Printf("%T, %b\n", square(byte(4)), square(byte(4)))
}
